
/* Copyright (C) 1988, 1989 Herve' Touati, Aquarius Project, UC Berkeley */

/* Copyright Herve' Touati, Aquarius Project, UC Berkeley */

% Adding initialization instructions
% in disjunctions to variables which need it.
% Result is a modified PartObj.
% Traverses code once; passes over everything without
% a passing glance except disjunctions.

% Must be used before tempalloc.

varinit(Forward, Backward, Partobj, Newobj) :-
	xvarinit(Forward, Backward, Partobj, Newobj-[]), !.

xvarinit([_], _, X, R-L) :- linkify(X, R-L), !.

% The first two clauses traverse Forward, Backward, and PartObj
% until a disjunction is found:
xvarinit([_,FIn|Forward], [_,BIn|Backward], PartObj, NewObj) :-
	'\+'(FIn=(_;_)), !, % Note: since Forward and Backward have identical
		        % structure, only one must be tested.
	xvarinit([FIn|Forward], [BIn|Backward], PartObj, NewObj), !.
xvarinit(Forward, Backward, [G|PartObj], [G|NewObj]-Link) :-
	'\+'(G=(_;_)), !,
	xvarinit(Forward, Backward, PartObj, NewObj-Link), !.

% At this stage all three arguments have disjunctions:
xvarinit([FLeft,(FA;FB),FRight|Forward],
	 [BLeft,(BA;BB),BRight|Backward], 
	 [(A;B)|PartObj], [(NA;NB)|NewObj]-Link) :- !,
	diffv(FRight, FLeft, T),
	intersectv(T, BRight, V),
	dis_varinit(V, (FA;FB), (BA;BB), (A;B), (NA;NB)),
	xvarinit([FRight|Forward], [BRight|Backward], PartObj, NewObj-Link), !.

dis_varinit(V, (FA;FB), (BA;BB), (A;B), (NA;NB)) :-
	one_choice(V, FA, BA, A, NA),
	dis_varinit(V, FB, BB, B, NB).
dis_varinit(V, FA, BA, A, NA) :-
	one_choice(V, FA, BA, A, NA).

one_choice(V, FA, BA, A, NA) :-
	xvarinit(FA, BA, A, NA-Link),
	last(FA, FLast),
	diffv(V, FLast, InitVars),
	add_init_list(InitVars, Link).

	add_init_list([], []) :- !.
	add_init_list(InitVars, [InitInstr]) :- init_list(InitVars, InitInstr).

init_list([V|Vars], [put(variable,V,V)|Rest]-Link) :-
	init_list(Vars, Rest-Link).
init_list([], Link-Link).
